public class Test {
    public static void main(String[] args) {
       /*//对于Solution这个有问题的版本进行调试
        Solution s = new Solution();
        int[] nums = new int[]{1, 2, 3, 4, 6, 7, 9, 10};
        int[] ret = new int[2];
        ret =s.missingTwo(nums);
        System.out.println(ret[0]);
        System.out.println(ret[1]);*/
    }
}

//↓↓↓这个是正确的！！！细心一点，慢一点，太快了可能会忽略很多，可能会写出很多不该出现的错误！！！
class Solution2 {
    public int[] missingTwo(int[] nums) {
        int len = nums.length;//nums 数组的长度
        int[] ret =  new int[2];

        //存放所有数的异或结果
        int tmp = 0;
        for(int x : nums)tmp^=x;
        for(int i = 1; i<=len+2;i++) tmp^=i;

        int diff = 0;//找出tmp中为1的位——也就是两个数不同的位。
        while(true){
            if((((tmp)>>diff)&1)==1){
                break;
            }else{
                diff++;
            }
        }

        //将这些数划到不同的阵营
        for(int x : nums){
            if((((x)>>diff)&1)==1){
                ret[1]^=x;
            }else{
                ret[0]^=x;
            }
        }
        for(int i = 1; i<=len+2;i++){
            if((((i)>>diff)&1)==1){
                ret[1]^=i;
            }else{
                ret[0]^=i;
            }
        }

        return ret;

    }
}

//有点问题。而且，写的有点乱，变量名也乱，传了git，记得改！！！
//消失的数字II（hard）
//https://leetcode.cn/problems/missing-two-lcci/
//↓↓↓这里是有问题的版本
class Solution {
    /**
     * ——这里。大概逻辑是按照老师讲的写的，但是就是写的不是很清楚。
     * 有问题，但是不知道在哪里。应该自己调试找找问题在哪里的。
     * 但是时间有点紧，在这个项目下重新写一遍吧
    * */

    public int[] missingTwo(int[] nums) {
        //要返回的数字
        int[] ret = new int[2];

        //计算^的和
        int tmp = 0;
        int p = 0;
        for(int n : nums){
            tmp ^=(nums[p] ^ p);
            p++;
        }
        tmp^=((p+1)^(p+2)^p);//这里一定要注意：循环结束后，p到底计数到多少了，以及，我们需要把p加到多少


        //找出是1的一位，把两个数分开（分类，到不同“阵营”。注意：这是要想分别得到这两个数所必须的）
        int m = 0;
        for(int i = 0;i<32;i++){
            tmp=(tmp>>i);
            if((tmp&1)==1){
                m = i;//其实这里不写也行，因为一定会有一位是1的//不对，要写的，i是局部变量，用不了
                break;
            }
        }

        //找出这两个数
        int x = 0;
        int y = 0;
        for(int i = 0; i<nums.length; i++){

            int n = ((nums[i]>>m)&1);
            if(n==1){
                x^=nums[i];
            }else{
                y^=nums[i];
            }

            /*int z = ((i>>m)&1);
            if(z==1){
                x^=i;
            }else{
                y^=i;
            }*/
        }

        for(int i = 0; i<=(nums.length+2); i++){
            //
            int flg = (i>>m);
            if(flg == 1){
                //
                x^=i;
            }else{
                y^=i;
            }
        }

        /*for(int k = 3;k>0;k--){
            int flg = ((p>>m)&1);
            if(flg==1){
                //
                x^=k;
            }else{
                //
                y^=k;
            }
            p+=1;
        }*/
        /*ret[0]=x;
        ret[1]=y;*/

        return ret;

    }
}